#pragma once
#include<vector>
#include<iostream>
#include<pthread.h>
#include<unistd.h>
#include<queue>
int const sum=5;
class BlockQueue{

    private:
    bool IsFull()
    {
return _q.size()>=_cap;
    }
    bool IsEmpty()
    {
return _q.size()==0;
    }
    public:
    BlockQueue()
    :_cap(sum),
    _csleep_sum(0),
    _psleep_sum(0)
    {
        pthread_mutex_init(&_mutex,nullptr);
        pthread_cond_init(&_full_cond,nullptr);
        pthread_cond_init(&_empty_cond,nullptr);
    }
void Equeue(const int in)//生产数据
{
    //生产者和消费者之间是互斥的
    pthread_mutex_lock(&_mutex);
    //满的时候不能生成
    while(IsFull())//解决wait函数失败的问题
    {
        //生产者要去休眠了
        _psleep_sum++;
        std::cout<<"生产者去休眠了,休眠个数:"<<_psleep_sum<<std::endl;
        //进行等待
        pthread_cond_wait(&_full_cond,&_mutex);
        _psleep_sum--;

    }
    //走到这里说明有空位置了
    _q.push(in);
    //唤醒一个消费者去消费
    pthread_cond_signal(&_empty_cond);
    //使用完毕，需要解锁
    pthread_mutex_unlock(&_mutex);

}

int  Pop()
{
    //消费和生产是互斥的，要先上锁
 pthread_mutex_lock(&_mutex);

 while(IsEmpty())//解决等待函数失败的问题
{
_csleep_sum++;
std::cout<<"生产者去休眠了,休眠个数:"<<_csleep_sum<<std::endl;
pthread_cond_wait(&_empty_cond,&_mutex);
_csleep_sum--;

}
//走到这里说明有资源可以消费
int ret=_q.front();
_q.pop();

//有空位置了，去唤醒生产者
pthread_cond_signal(&_full_cond);



 //解锁
 pthread_mutex_unlock(&_mutex);
 return ret;

}

    ~BlockQueue()
    {
        pthread_mutex_destroy(&_mutex);
        pthread_cond_destroy(&_full_cond);
        pthread_cond_destroy(&_empty_cond);
    }
    


    private:
    std::queue<int> _q;
    int _cap;
    pthread_mutex_t _mutex;
    pthread_cond_t _full_cond;
    pthread_cond_t _empty_cond;
    int _csleep_sum;
    int _psleep_sum;
};